{
 "metadata": {
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7-final"
  },
  "orig_nbformat": 2,
  "kernelspec": {
   "name": "python3",
   "display_name": "Python 3.7.7 64-bit ('base': conda)",
   "metadata": {
    "interpreter": {
     "hash": "299afe6299b24d6e3f062b8efb6f58349b7f24979b10bbd48accc74df63407e6"
    }
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2,
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "input_file = 'results.csv'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df = pd.read_csv(input_file, comment='#')\n",
    "markers = ['o', '+', 'x', '*', 'p', 'X', 'd', 'D', 'v', 's']\n",
    "colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf']\n",
    "class_names = sorted(set([re.sub('<.*>', \"\", x) for x in df.class_name.unique()]))\n",
    "dataset_names = df.dataset.unique()\n",
    "ncols = min(3, len(dataset_names))\n",
    "nrows = -(-len(dataset_names) // ncols)\n",
    "fig, axs = plt.subplots(constrained_layout=True, ncols=ncols, nrows=nrows, squeeze=False, figsize=(5.3 * ncols, 4.5 * nrows))\n",
    "\n",
    "for dataset, ax in zip(dataset_names, axs.flat):\n",
    "    ax.set_prop_cycle(marker=markers, color=colors)\n",
    "\n",
    "    for class_name in class_names:\n",
    "        d = df[(df.dataset == dataset) & (df.class_name.str.startswith(class_name))]\n",
    "        ax.plot(d.bytes, d.query_ns, label=class_name, linestyle='None', markersize=5)\n",
    "\n",
    "    max_bytes = df[(df.dataset == dataset)].bytes.max()\n",
    "    try:\n",
    "        from cpufeature import CPUFeature as cpu\n",
    "        if cpu['cache_L1_size'] < max_bytes: ax.axvline(x=cpu['cache_L1_size'], lw=0.6, c='k', label='Cache sizes')\n",
    "        if cpu['cache_L2_size'] < max_bytes: ax.axvline(x=cpu['cache_L2_size'], lw=0.6, c='k')\n",
    "        if cpu['cache_L3_size'] < max_bytes: ax.axvline(x=cpu['cache_L3_size'], lw=0.6, c='k')\n",
    "    except:\n",
    "        print('To plot also the cache sizes, run: pip3 install cpufeature')\n",
    "\n",
    "    ax.set_title(dataset)\n",
    "    ax.set_xscale('log')\n",
    "    ax.legend(fontsize='x-small')\n",
    "    ax.grid(which='both', linestyle=':', lw=0.5)\n",
    "    ax.set_ylabel('Query time (ns)')\n",
    "    ax.yaxis.set_minor_locator(mpl.ticker.AutoMinorLocator(2))\n",
    "    if max_bytes < 1e6:\n",
    "        ax.set_xlabel('Index size (KB)')\n",
    "        ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter(lambda y, _: '{:g}'.format(y / 1e3)))\n",
    "    else:\n",
    "        ax.set_xlabel('Index size (MB)')\n",
    "        ax.xaxis.set_major_formatter(mpl.ticker.FuncFormatter(lambda y, _: '{:g}'.format(y / 1e6)))\n",
    "\n",
    "plt.savefig('plot.pdf')\n",
    "plt.show()"
   ]
  }
 ]
}